package com.sh.data.engine.iotdb.domain;

import com.google.common.collect.Lists;
import com.sh.data.engine.velocity.model.iotdb.IotDataModel;
import com.sh.data.engine.velocity.model.iotdb.IotDataModel.MeasurementModel;
import lombok.Data;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;

import java.util.Arrays;
import java.util.List;

@Data
public class TabletDomain {
    private String deviceId;
    // 包含测点名和测点数据类型
    private List<MeasurementSchema> schemaList;
    private int maxRowNumber = 100;
    private List<TabletDataSet> tabletDataSets;

    @Data
    public static class TabletDataSet {
        private List<Object> values; // 测点数据集合
        private Long timestamp; // 时间戳
    }

    // 算盘组件加入的字段
    private List<Object> insertValues;

    // 算盘组件加入的字段
    private List<Long> timestamps;

    public static TabletDomain generateFromIOTModel(IotDataModel dataModel) {
        if (dataModel.isInvalid()) {
            return null;
        }
        TabletDomain tabletDomain = new TabletDomain();
        tabletDomain.setDeviceId(
            String.join(".", dataModel.getStorageGroup(), dataModel.getDeviceId()));

        List<MeasurementModel> measurements = dataModel.getMeasurements();
        List<MeasurementSchema> schemaList = Lists.newArrayList();

        TabletDataSet tabletDataSet = new TabletDataSet();
        List<Object> values = Lists.newArrayList();
        tabletDataSet.setTimestamp(dataModel.getTimestamp());
        measurements.stream()
            // TODO 解析为tsdatatype
            .forEach(
                co -> {
                    schemaList.add(
                        new MeasurementSchema(co.getName(), TabletDomain.toTsDataType(co.getValue())));
                    values.add(co.getValue());
                });
        tabletDomain.setSchemaList(schemaList);
        tabletDataSet.setValues(values);
        tabletDomain.setTabletDataSets(Arrays.asList(tabletDataSet));
        return tabletDomain;
    }

    private static TSDataType toTsDataType(Object value) {
        TSDataType tsDataType = null;
        String className = value.getClass().getName();
        switch (className) {
            case "java.lang.Integer":
                tsDataType = TSDataType.INT32;
                break;
            case "java.lang.Long":
                tsDataType = TSDataType.INT64;
                break;
            case "java.lang.Double":
                tsDataType = TSDataType.DOUBLE;
                break;
            case "java.lang.Float":
                tsDataType = TSDataType.FLOAT;
                break;
            case "java.lang.Boolean":
                tsDataType = TSDataType.BOOLEAN;
                break;
            case "java.lang.String":
            default:
                tsDataType = TSDataType.TEXT;
                break;
        }
        return tsDataType;
    }
}
